#include <iostream>
#include <string>

using namespace std;

//==============================================================================

class DateImpl;

class Date {
public:
				 ~Date();
				 Date(const string& Impl, int day, int month );
	virtual void tell();

	int getDay() const;
	int getMonth() const;
protected:
	DateImpl*  m_Date;
};

//==============================================================================

class DateImpl {
public:
	DateImpl( int day, int month ) { d = day;  m = month; }

	virtual void	tell() = 0;
	int				getDay() const		{ return d;}
	int				getMonth() const	{ return m;}
protected:
   int d, m;
};

//==============================================================================

class HebrewDateImpl : public DateImpl {
public:
	HebrewDateImpl( int day, int month) 
		: DateImpl( day, month ) {/*..*/ }

	virtual void tell() { 
	   cout << "Hebrew Date is :" << d <<"/" << m << endl; 
	}
};

//==============================================================================

class ArabicDateImpl : public DateImpl {
public:
	ArabicDateImpl( int day, int month) 
		: DateImpl( day, month ) {/*..*/ }

	virtual void tell() { 
	   cout << "Arabic Date is :" << d <<"/" << m << endl; 
	}
};

//==============================================================================

class DateFactory {
public:
	static DateImpl* CreateDate(const string& Impl, int day, int month ) {
		DateImpl* ptrDate = 0;
  		if (Impl == "Hebrew")   
			ptrDate = new HebrewDateImpl( day, month );
  		if (Impl == "Arabic") 
			ptrDate = new ArabicDateImpl( day, month );
		return ptrDate;
	};
private:
	~DateFactory();
	DateFactory();
};

//==============================================================================

Date::~Date()  {
	delete m_Date;				// delete implementation creted by Factory
	m_Date=0;
}

Date::Date(const string& Impl, int day, int month ) {
	m_Date = DateFactory::CreateDate(Impl, day, month);	
	// Use factory to creater Date over any implemetations
	// If new implementations will be added the Date class willn't be changed !!!
	// the only change will be in Factory
}

void Date::tell() {				// just rederection to implementation class
	m_Date->tell(); 
}

int Date::getDay() const {		// just rederection to implementation class
	return m_Date->getDay();
}

int Date::getMonth() const {	// just rederection to implementation class
	return m_Date->getMonth();
}

//==============================================================================


//==============================================================================

void main() {
	int i;
	Date*  Dates[2];
	Dates[0] = new Date("Hebrew",  2, 12);
	Dates[1] = new Date("Arabic", 14, 11);
	for ( i=0; i < 2; i++)
		Dates[i]->tell();
}

